/**********************************************************************
 *   Copyright: (C)2024 LingYun IoT System Studio
 *      Author: LiJiahui<2199250859@qq.com>
 *
 * Description: Provides BLE-related AT command sending
 * 				and data reporting functions for ESP32 modules
 *
 *   ChangeLog:
 *        Version    Date       Author            Description
 *        V1.0.0  2025.07.18    LiJiahui      Release initial version
 *
 ***********************************************************************/

#include "ble_send.h"

#define CONFIG_BLE_DEBUG
#ifdef CONFIG_BLE_DEBUG
#define ble_printf(format, args...) printf(format, ##args)
#else
#define ble_printf(format, args...) do{} while(0)
#endif



/* ----------------------------------- Functions used in FreeRTOS --------------------------- */
//BLE初始化
int ble_module_init(SemaphoreHandle_t xUartMutex)
{
	// 获取 UART 互斥锁，保护整个初始化流程
	if (xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(10000)) != pdPASS)
	{
		ble_printf("Failed to get UART mutex for BLE init.\r\n");
		return BLE_INIT_FAILURE_MUTEX;
	}

	ble_printf("Starting BLE module initialization...\r\n");

	// 1. 检查模块是否响应
	ble_printf("1. Sending AT command...\r\n");
	if (esp8266_send_command("AT\r\n", BLE_RESPONSE_OK, 1000) != NTP_SUCCESS)
	{
		ble_printf("   -> Failed: No AT response.\r\n");
		xSemaphoreGive(xUartMutex);
		return BLE_INIT_FAILURE_AT;
	}

	// 2. 初始化 BLE 为外围设备模式
	ble_printf("2. Initializing BLE to Peripheral mode...\r\n");
	if (esp8266_send_command("AT+BLEINIT=2\r\n", BLE_RESPONSE_OK, 1000)
			!= NTP_SUCCESS)
	{
		ble_printf("   -> Failed: AT+BLEINIT=2.\r\n");
		xSemaphoreGive(xUartMutex);
		return BLE_INIT_FAILURE_INIT;
	}

	// 3. 创建 GATT 服务和特性
	ble_printf("3. Creating GATT Service and Characteristics...\r\n");
	if (esp8266_send_command("AT+BLEGATTSSRVCRE\r\n", BLE_RESPONSE_OK, 2000)
			!= NTP_SUCCESS)
	{
		ble_printf("   -> Failed: AT+BLEGATTSSRVCRE.\r\n");
		xSemaphoreGive(xUartMutex);
		return BLE_INIT_FAILURE_SRVCRE;
	}

	// 4. 启动 GATT 服务
	ble_printf("4. Starting GATT Service...\r\n");
	if (esp8266_send_command("AT+BLEGATTSSRVSTART\r\n", BLE_RESPONSE_OK, 1000)
			!= NTP_SUCCESS)
	{
		ble_printf("   -> Failed: AT+BLEGATTSSRVSTART.\r\n");
		xSemaphoreGive(xUartMutex);
		return BLE_INIT_FAILURE_SRVSTART;
	}

	// 5. 设置广播数据
	ble_printf("5. Setting Advertisement Data...\r\n");
	if (esp8266_send_command(
			"AT+BLEADVDATA=\"0201060B0945737033325F424C45\"\r\n",
			BLE_RESPONSE_OK, 1000) != NTP_SUCCESS)
	{
		ble_printf("   -> Failed: AT+BLEADVDATA.\r\n");
		xSemaphoreGive(xUartMutex);
		return BLE_INIT_FAILURE_ADVDATA;
	}

	// 6. 启动广播
	ble_printf("6. Starting Advertisement...\r\n");
	if (esp8266_send_command("AT+BLEADVSTART\r\n", BLE_RESPONSE_OK, 1000)
			!= NTP_SUCCESS)
	{
		ble_printf("   -> Failed: AT+BLEADVSTART.\r\n");
		xSemaphoreGive(xUartMutex);
		return BLE_INIT_FAILURE_ADVSTART;
	}

	ble_printf("BLE module initialized successfully.\r\n");

	xSemaphoreGive(xUartMutex); // 释放 UART 互斥锁
	return BLE_INIT_SUCCESS;
}


//断开连接后重新发送广播
int ble_adv_start(SemaphoreHandle_t xUartMutex)
{
    int retry_count = 0;
    int result = -1;

    // 重试循环
    while (retry_count < MAX_RETRY_ATTEMPTS)
    {
        printf("Starting Advertisement... (Attempt %d/%d)\r\n", retry_count + 1, MAX_RETRY_ATTEMPTS);

        // 尝试获取互斥锁
        if (xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(MUTEX_TIMEOUT_MS)) == pdTRUE)
        {
            // 成功获取锁，发送AT命令
            if (esp8266_send_command("AT+BLEADVSTART\r\n", BLE_RESPONSE_OK, CMD_TIMEOUT_MS) == NTP_SUCCESS)
            {
                printf("   -> Advertisement started successfully. Waiting for reconnect.\r\n");
                result = 0; // 成功
                xSemaphoreGive(xUartMutex); // 成功后释放锁
                break; // 成功，跳出重试循环
            }
            else
            {
                printf("   -> Failed: AT+BLEADVSTART. Retrying...\r\n");
                // 命令发送失败，释放锁，准备重试
                xSemaphoreGive(xUartMutex);
            }
        }
        else
        {
            printf("   -> Failed to take UartMutex. Retrying...\r\n");
            // 获取锁失败，无需释放，直接准备重试
        }

        // 增加重试计数器
        retry_count++;
        // 延时一段时间，防止重试过快
        vTaskDelay(pdMS_TO_TICKS(RETRY_DELAY_MS));
    }

    if (result != 0)
    {
        printf("BLE: Advertisement start failed after %d retries. Halting or proceeding with caution.\r\n", MAX_RETRY_ATTEMPTS);
    }

    return result;
}


//发送传感器数据
int ble_send_sensor_data(SemaphoreHandle_t xUartMutex, uint16_t heart_rate, uint16_t spo2)
{
	int rv = -1;

	// 在发送数据前，获取 UART 互斥锁
	// 设置一个超时时间，防止因其他任务死锁而永久等待
	if (xSemaphoreTake(xUartMutex, pdMS_TO_TICKS(100)) != pdTRUE)
	{
		ble_printf("Failed to acquire UART mutex for BLE data send.\r\n");
		return -3;
	}

	// 构造负载数据
	char data[64];
	int len = snprintf(data, sizeof(data), "HR:%03d,SpO2:%03d", heart_rate,
			spo2);

	// 构造通知命令
	// 假设 conn_id=0, srv_idx=1, char_idx=6
	char cmd[64];
	snprintf(cmd, sizeof(cmd), "AT+BLEGATTSNTFY=0,1,6,%d\r\n", len);

	ble_printf("sending AT command: %s", cmd);

	// 等待 ">" 提示符
	rv = esp8266_send_command(cmd, ">", 3000);
	if (rv != NTP_SUCCESS)
	{
		ble_printf("error: notify command failed or did not receive '>'\r\n");
		xSemaphoreGive(xUartMutex);
		return -4;
	}

	// 收到 '>' 提示符后，发送数据负载
	ble_printf("sending data: %s\r\n", data);
	if (HAL_UART_Transmit(&huart2, (unsigned char*) data, len, 5000) != HAL_OK)
	{
		ble_printf("send data failure\r\n");
		rv = -5;
	}
	else
	{
		ble_printf("BLE data send successful\r\n");
		rv = NTP_SUCCESS;
	}

	xSemaphoreGive(xUartMutex);
	return rv;
}
